<template>
  <a-modal
    v-model:visible="visible"
    :mask-closable="false"
    :escToClose="false"
    title="免押码"
    width="45vw"
    :body-style="{ padding: '16px 20px' }"
    unmount-on-close
    @close="onClose"
  >
    <div class="deposit-content">
      <a-spin style="width: 100%" :loading="loading" tip="加载中...">
        <template v-if="!emptyStatus">
          <!-- 编辑状态 -->
          <template v-if="validDepositStatus">
            <div class="tips">
              <icon-exclamation-circle />
              押金金额说明：
              <span class="normal"> 还车后从租车押金中转 {{ form.illegalDeposit }} 元至违章押金，剩余可退。 </span>
            </div>
            <div class="member-info">
              <div class="member-info-title">承租人信息</div>
              <div class="member-info-content">
                <div class="member-info-item">
                  <div class="member-info-item-label">承租人姓名：</div>
                  <div class="member-info-item-content">{{ form.memberName }}</div>
                </div>
                <div class="member-info-item">
                  <div class="member-info-item-label">承租人手机号：</div>
                  <div class="member-info-item-content">{{ form.memberPhone }}</div>
                </div>
              </div>
            </div>
            <a-divider style="margin-bottom: 25px" />
            <page-form :model="form" layout="vertical" style="overflow: hidden">
              <page-form-row :gutter="56">
                <page-form-item v-for="(label, key) in depositTypes" :key="key" :label="label" size="1/2" :field="key">
                  <template #label-extra>
                    <div v-if="editStatus === key">
                      <a class="a-link red" @click="saveAmount(key)">
                        <img class="icon" src="@/assets/alipay-deposit/save.png" />
                        保存金额
                      </a>
                    </div>
                    <div v-else>
                      <a class="a-link blue" @click="editAmount(key)">
                        <img class="icon" src="@/assets/alipay-deposit/edit.png" />
                        修改金额
                      </a>
                    </div>
                  </template>
                  <a-input-number
                    v-model="tempForm[key]"
                    :max="99999999.99"
                    :min="0"
                    hide-button
                    :precision="2"
                    :disabled="editStatus !== key"
                  />
                </page-form-item>
                <page-form-item label="需授权押金" size="1/2" field="authorizeMoney">
                  <a-input-number v-model="form.authorizeMoney" :max="99999999.99" :min="0" :precision="2" hide-button disabled />
                </page-form-item>
              </page-form-row>
            </page-form>
            <div class="title" v-if="showQRCode && form.imgUrl">({{ epName }}-支付宝免押)请将下面二维码发客户使用支付宝扫描进行免押</div>
          </template>
          <!-- 仅查看状态 -->
          <template v-if="!validDepositStatus">
            <a-descriptions class="my-descriptions" layout="inline-horizontal">
              <a-descriptions-item label="承租人姓名">{{ form.memberName }}</a-descriptions-item>
              <a-descriptions-item label="承租人手机号" :span="2">{{ form.memberPhone }}</a-descriptions-item>
              <a-descriptions-item label="租车押金">{{
                form.carDeposit || form.carDeposit === 0 ? `${form.carDeposit} 元` : '-'
              }}</a-descriptions-item>
              <a-descriptions-item label="违章押金">{{
                form.illegalDeposit || form.illegalDeposit === 0 ? `${form.illegalDeposit} 元` : '-'
              }}</a-descriptions-item>
              <a-descriptions-item label="需授权押金">{{
                form.authorizeMoney || form.authorizeMoney === 0 ? `${form.authorizeMoney} 元` : '-'
              }}</a-descriptions-item>
            </a-descriptions>
          </template>
          <!-- 二维码共用 -->
          <div class="qr-code-wrapper" v-if="(showQRCode && form.imgUrl) || iconSrc">
            <div class="qr-code">
              <!-- 二维码 -->
              <img class="qr-image" v-if="showQRCode" :src="form.imgUrl" alt="二维码" />
              <!-- 订单状态 ICON 外层 -->
              <div class="icon-container" v-if="iconSrc">
                <img class="icon-status" :src="iconSrc" alt="状态图标" />
              </div>
            </div>
          </div>
          <!-- 二维码加载中 -->
          <div class="qr-code-loading" v-if="imgUrlFetching">
            <a-spin tip="二维码加载中..." />
          </div>
        </template>
        <template v-else>
          <div class="flex">芝麻免押开关已关闭，请联系管理员</div>
        </template>
      </a-spin>
    </div>
    <template #footer>
      <a-space>
        <a-button @click="visible = false">关闭</a-button>
      </a-space>
    </template>
  </a-modal>
</template>

<script setup>
  import { ref, computed } from 'vue'
  import useUserStore from '@/store/modules/user'
  import { Message } from '@arco-design/web-vue'
  import { getFreeDepositCodeInfo, getFreeDepositCode, changeDepositAmount } from '@/api/order/sOrder'

  const userStore = useUserStore()
  // 读取商户配置
  userStore.setEpDetail()
  //商户简称
  const epName = computed(() => userStore.briefName || projectName)
  // 是否显示二维码
  const showQRCode = computed(() => {
    let isEdit = editStatus.value
    let carDeposit = form.value.carDeposit
    let illegalDeposit = form.value.illegalDeposit
    return !isEdit && carDeposit > 0 && carDeposit >= illegalDeposit
  })
  // 二维码加载中
  const imgUrlFetching = ref(false)
  // 有效二维码
  const validDepositStatus = computed(() => {
    const { depositPayType, orderStatus } = form.value
    const isDepositNotUsed = depositPayType == 1
    const isOrderActive = ![-100, 300, 1000, -1000].includes(orderStatus)
    return isDepositNotUsed && isOrderActive
  })
  // icon状态展示
  const iconSrc = computed(() => {
    // 押金支付方式: 1 未缴纳 2 线下收款 3 网络平台代收 4 芝麻免押
    const depositPayType = form.value.depositPayType
    // 订单状态: 10 待排车 100 待交车 200 用车中 300 已还车 1000 已完成 -100 已取消
    const orderStatus = form.value.orderStatus
    // 情况1：免押码如果已经被使用了
    if (depositPayType == 4) {
      return new URL(`@/assets/alipay-deposit/short-icon4.png`, import.meta.url).href
    }
    // 情况2：线下已缴纳，失效
    if (depositPayType == 2 || depositPayType == 3) {
      return new URL(`@/assets/alipay-deposit/short-icon5.png`, import.meta.url).href
    }
    // 免押码未使用
    if (depositPayType == 1) {
      // 情况3：订单状态到已取消或已完成的、已还车
      // 已还车、已完成、已取消
      if ([300, 1000, -100].includes(orderStatus)) {
        if (orderStatus == -100) {
          return new URL(`@/assets/alipay-deposit/short-icon1.png`, import.meta.url).href
        }
        if (orderStatus == 1000) {
          return new URL(`@/assets/alipay-deposit/short-icon2.png`, import.meta.url).href
        }
        if (orderStatus == 300) {
          return new URL(`@/assets/alipay-deposit/short-icon7.png`, import.meta.url).href
        }
      }
      // 情况4：待排车、待交车、用车中，校验是否开启芝麻免押
      if ([10, 100, 200].includes(orderStatus)) {
        // 芝麻免押服务未开启
        if (userStore.epAlipaySwitch != 1) {
          return new URL(`@/assets/alipay-deposit/short-icon3.png`, import.meta.url).href
        }
      }
    }
    return null
  })
  const visible = ref(false)
  const editStatus = ref(null) // 当前正在编辑的押金类型

  const form = ref({
    carDeposit: '',
    illegalDeposit: '',
    authorizeMoney: '',
    imgUrl: '',
  })

  const tempForm = ref({ ...form.value }) // 临时存储数据，避免未保存时直接修改

  const depositTypes = {
    carDeposit: '租车押金',
    illegalDeposit: '违章押金',
  }

  // 展示弹窗
  const id = ref()
  const loading = ref(false)
  const emptyStatus = ref(false)
  /**
   * 设置免押码信息
   */
  const setDepositCodeDetail = (detail) => {
    form.value = detail
    form.value.authorizeMoney = form.value.carDeposit
    // 判断如果没有二维码，获取二维码
    if (!detail.fileId) {
      if (showQRCode.value) {
        imgUrlFetching.value = true
      }
      getFreeImgCodeUrl(id.value)
    } else {
      form.value.imgUrl = `${import.meta.env.VITE_BASE_PATH}/uploadFile/image/${form.value.fileId}`
    }
    tempForm.value = { ...form.value } // 同步初始数据
  }
  const show = (record) => {
    visible.value = true
    id.value = record.id
    editStatus.value = null
    loading.value = true
    getFreeDepositCodeInfo({ id: record.id, selectType: 2 })
      .then((res) => {
        if (res.result) {
          emptyStatus.value = false
          // 设置免押码信息
          setDepositCodeDetail(res.result)
          // 轮询获取免押码状态，初次冷却4秒
          startPollingGetDepositStatus(4000)
        } else {
          emptyStatus.value = true
        }
      })
      .catch((error) => {
        console.log('error', error)
        emptyStatus.value = true
      })
      .finally(() => {
        loading.value = false
      })
  }

  /**
   * @param {Object} option
   * @param {Number} option.depositPayType 押金支付方式: 1 未缴纳 2 线下收款 3 网络平台代收 4 芝麻免押
   * @param {Number} option.orderStatus 订单状态: 10 待排车 100 待交车 200 用车中 300 已还车 1000 已完成 -100 已取消
   * @returns {Boolean} 免押码是否可用
   */
  const getFreeCodeIsCanUse = (option) => {
    // 押金支付方式: 1 未缴纳 2 线下收款 3 网络平台代收 4 芝麻免押
    const depositPayType = option.depositPayType
    // 订单状态: 10 待排车 100 待交车 200 用车中 300 已还车 1000 已完成 -100 已取消
    const orderStatus = option.orderStatus
    // 情况1：免押码已经被使用
    if (depositPayType == 4) {
      return false
    }
    // 情况2：线下已缴纳，失效
    if (depositPayType == 2 || depositPayType == 3) {
      return false
    }
    // 免押码未使用
    if (depositPayType == 1) {
      // 情况3：订单状态到已取消或已完成的、已还车
      if ([300, 1000, -100].includes(orderStatus)) {
        return false
      }
      // 情况4：待排车、待交车、用车中，但未开启芝麻免押服务
      if ([10, 100, 200].includes(orderStatus) && userStore.epAlipaySwitch != 1) {
        return false
      }
    }

    return true
  }
  // 判断是否免押码从未使用变成了已使用
  const hasEditStatusChange = (newOption) => {
    // 免押码是否可用
    const oldIsCanUse = getFreeCodeIsCanUse(form.value)
    const newIsCanUse = getFreeCodeIsCanUse(newOption)
    if (oldIsCanUse && !newIsCanUse) {
      return true
    }
    return false
  }

  /**
   * 轮询获取免押码状态
   * @param {Number} sleep 延时，单位毫秒
   */
  const startPollingGetDepositStatus = (sleep = 1000) => {
    // 延时获取最新的免押码状态
    setTimeout(() => {
      // 弹窗开启并且当前免押码属于可扫码状态
      if (visible.value && getFreeCodeIsCanUse(form.value)) {
        console.log('轮询获取免押码状态...')
        getFreeDepositCodeInfo({ id: id.value, selectType: 2 }).then((res) => {
          if (res.result) {
            // 监听到免押码变成已使用
            const detectedChange = hasEditStatusChange(res.result)
            // 轮询终止
            if (detectedChange) {
              console.log('免押码状态已改变，终止轮询')
              // 重置编辑状态
              editStatus.value = null
              setDepositCodeDetail(res.result)
            } else {
              // 继续轮询
              startPollingGetDepositStatus(2000)
            }
          }
        })
      } else {
        if (!visible.value) console.log('弹窗关闭，终止轮询')
      }
    }, sleep)
  }

  /**
   * 获取免押码二维码
   * @param orderId 订单id
   */
  const getFreeImgCodeUrl = (orderId) => {
    getFreeDepositCode({ id: orderId, selectType: 2 })
      .then((res) => {
        const fileId = res.result
        if (fileId) {
          form.value.imgUrl = `${import.meta.env.VITE_BASE_PATH}/uploadFile/image/${fileId}`
        }
        imgUrlFetching.value = false
      })
      .catch(() => {
        imgUrlFetching.value = false
      })
  }

  // 关闭弹窗时重置数据
  const onClose = () => {
    visible.value = false
    imgUrlFetching.value = false
    editStatus.value = null
    loading.value = false
    emptyStatus.value = false
    form.value = {}
    tempForm.value = {} // 关闭时恢复初始数据
  }

  // 点击“修改金额”按钮
  const editAmount = (key) => {
    if (editStatus.value !== null && editStatus.value !== key) {
      tempForm.value[editStatus.value] = form.value[editStatus.value] // 恢复未保存的旧值
    }
    editStatus.value = key // 设为当前编辑项
  }

  // 点击“保存金额”按钮
  const saveAmount = (key) => {
    if (!tempForm.value[key] && tempForm.value[key] !== 0) {
      Message.error('请输入金额')
      return
    }
    changeDepositAmount({
      id: id.value,
      depositType: key === 'carDeposit' ? 1 : 2, //1：租车押金   2：违章押金
      depositAmount: tempForm.value[key],
    }).then((res) => {
      if (res.code == 200) {
        form.value[key] = tempForm.value[key] // 保存后更新正式数据
        if (key === 'carDeposit') {
          form.value.authorizeMoney = form.value.carDeposit
        }
        editStatus.value = null // 退出编辑状态
        Message.success('修改成功')
      } else {
        Message.error(res.message)
      }
    })
  }

  defineExpose({ show, onClose })
</script>

<style lang="less" scoped>
  .tips {
    width: 100%;
    height: 40px;
    background: #e8f3ff;
    border-radius: 2px;
    font-weight: 600;
    font-size: 12px;
    color: #1890ff;
    line-height: 40px;
    padding-left: 16px;
    margin-bottom: 16px;
    .normal {
      color: #1d2129;
    }
  }
  .a-link {
    font-weight: 400;
    font-size: 14px;
    cursor: pointer;
    display: flex;
    align-items: center;
    .icon {
      width: 16px;
      height: 16px;
    }
  }
  .blue {
    color: #1890ff;
  }
  .red {
    color: #f53f3f;
  }
  .title {
    font-weight: 400;
    font-size: 16px;
    color: #1890ff;
    line-height: 34px;
    text-align: center;
  }
  .qr-code-wrapper {
    display: flex;
    justify-content: center;
  }
  .member-info {
    .member-info-title {
      font-weight: 600;
      font-size: 16px;
      color: #1d2129;
      line-height: 24px;
      margin-bottom: 12px;
    }
    .member-info-content {
      display: flex;
      .member-info-item {
        display: flex;
        .member-info-item-label {
          font-size: 14px;
          color: #4e5969;
        }
        .member-info-item-content {
          font-size: 14px;
          color: #1d2129;
        }
      }
      .member-info-item + .member-info-item {
        margin-left: 96px;
      }
    }
  }
  .my-descriptions {
    /deep/ .arco-descriptions-row:nth-child(2) {
      height: 42px;
    }
  }

  .qr-code {
    width: 120px;
    min-height: 120px;
    position: relative;
    margin-top: 12px;
    background: #d8d8d8;
  }

  .qr-image {
    width: 100%;
    height: 100%;
    display: block;
    backdrop-filter: blur(10px); /* 添加磨砂效果 */
  }

  .icon-container {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    background: rgba(255, 255, 255, 0.73);
  }

  .icon-status {
    width: 104px;
    opacity: 0.9; /* 透明度减少遮挡 */
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }
  .qr-code-loading {
    height: 170px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
</style>
